#include "SecondModule.h"

SecondModule::SecondModule(NxScene* scene, NxVec3 position): m_object(scene), m_position(position), m_scene(scene)
{}

SecondModule::~SecondModule(void)
{}

NxActor* SecondModule::CreateSecondModule(void)
{
	//create the canon
	NxVec3 canonPosition = NxVec3(0, 0, 0) + m_position;
	createCanon(canonPosition, NxVec3((float)-3.14/4, (float)-3.14/2, 0));

	//create the ball
	NxActor* bullet = m_object.CreateSphere(NxVec3(0, (float)2.3, 0)+m_position, 0.5, 2, 0, 0, 1);
	//NxVec3 initialVelocitiy(-cos(3.14/4), sin(3.14/4), 0);
	//initialVelocitiy = initialVelocitiy*70;
	//bullet->setLinearVelocity(initialVelocitiy);

	//create the first gear
	NxVec3 positionGear1 = NxVec3(-11, 10, 0) + m_position;
	createGear(positionGear1, 1, (float)-3.14/4);

	//create the second gear
	NxVec3 positionGear2 = NxVec3(-11, (float)7.3, 0) + m_position;
	createGear(positionGear2, 1, (float)-3.14/2);

	//create the ground
	NxVec3 groundSize(3, (float)0.1, 2);
	NxVec3 groundPosition(-12, 4, 0);
	m_object.CreateKinematicBox(groundSize, groundPosition+m_position, NxVec3(0, 0, 0), NxVec3(0.5, 0.5, 1));

	//football
	NxVec3 footballPosition(-11, (float)4.7, 0);
	float footballRadius = (float)0.7;
	float footballMass = 1;
	m_object.CreateSphere(footballPosition + m_position, footballRadius, footballMass, 0.5, 0.5, 1);

	//seesaw
	NxVec3 seesawPosition(-17, 5, 0);
	createSeesaw(seesawPosition+m_position);

	//create a block to stop the seesaw
	NxVec3 blockBox(5, (float)0.1, 2);
	NxVec3 blockPosition(-15, (float)3.8, 0);
	m_object.CreateKinematicBox(blockBox, blockPosition + m_position, NxVec3(0, 0, 0), NxVec3(0, 0, 1));

	//create the second ground for the cube
	NxVec3 secondGroundSize(1, (float)0.1, 2);
	NxVec3 secondGroundPosition((float)-19.8, 4, 0);
	m_object.CreateKinematicBox(secondGroundSize, secondGroundPosition + m_position, NxVec3(0, 0, 0), NxVec3(0, 0, 1));

	//create the cube
	NxVec3 cubeSize((float)0.7, (float)0.7, (float)0.7);
	NxVec3 cubePosition((float)-20.5, (float)4.8, 0);
	NxVec3 cubeDfSfR((float)0.1, (float)0.2, 1);
	m_object.CreateBox(cubeSize, cubePosition + m_position, cubeDfSfR, 2);

	//create the slope
	NxVec3 slopeSize(5, (float)0.2, 2);
	NxVec3 positionSlope((float)-24.7, 1, 0);
	NxVec3 rotationSlope(0, 0, (float)3.14/5);
	NxVec3 frictionSlope((float)0.1, (float)0.1, 0);
	m_object.CreateKinematicBox(slopeSize, positionSlope + m_position, rotationSlope, frictionSlope);

	//create the wall
	NxVec3 wallSize((float)0.2, 3, 2);
	NxVec3 positionWall(-30, 0, 0);
	NxVec3 rotationWall(0, 0, 0);
	NxVec3 frictionWall(1, 1, 0);
	m_object.CreateKinematicBox(wallSize, positionWall+ m_position, rotationWall, frictionWall);
	
	//create ground
	NxVec3 sizeGround(2, (float)0.2, 2);
	NxVec3 positionGround(-28, 0, 0);
	NxVec3 rotationGround(0, 0, 0);
	NxVec3 frictionGround(0, 0, 0);
	m_object.CreateKinematicBox(sizeGround, positionGround + m_position, rotationGround, frictionGround);

	return bullet;
}

void SecondModule::createCanon(const NxVec3& position, const NxVec3& rotation)
{
	float wheelSize = 0.5;
	const float canonLength = 2;

	//actor description
	NxActorDesc actorDesc;

	//create the first wheel
	NxBoxShapeDesc wheel1;
	wheel1.dimensions.set(wheelSize, wheelSize, wheelSize);
	wheel1.localPose.t = NxVec3(-1, wheelSize, 0);

	//create the second wheel
	NxBoxShapeDesc wheel2;
	wheel2.dimensions.set(wheelSize, wheelSize, wheelSize);
	wheel2.localPose.t = NxVec3(1, wheelSize, 0);

	//create the back
	NxBoxShapeDesc back;
	back.dimensions.set(1, 1, (float)0.1);
	back.localPose.t = NxVec3(0, (float)1.9, -canonLength/2);
	actorDesc.shapes.push_back(&back);

	NxBoxShapeDesc canon[10];
	//create the canon
	for(int i=0; i<10; i++)
	{
		

		//create the second wheel
		canon[i].dimensions.set((float)0.2, (float)0.5, canonLength);
		float angle = (float)(0.2*3.14*i);
		canon[i].localPose.M.rotZ(angle);
		canon[i].localPose.t = NxVec3((float)cos(angle), (float)(wheelSize*3.5+sin(angle)), (float)canonLength/2);
		actorDesc.shapes.pushBack(&canon[i]);
	}

	
	actorDesc.shapes.pushBack(&wheel1);
	actorDesc.shapes.pushBack(&wheel2);
	actorDesc.density		= 10.0f;
	actorDesc.globalPose.t	= position;

	//apply the rotation
	NxMat33 rotationMatrixX;
	rotationMatrixX.rotX(rotation.x);

	NxMat33 rotationMatrixY;
	rotationMatrixY.rotY(rotation.y);

	actorDesc.globalPose.M = rotationMatrixY*rotationMatrixX;
	
	m_scene->createActor(actorDesc);
}

void SecondModule::createGear(const NxVec3& position, float radius, float rotationZ)
{
	//shape descriptor
	NxSphereShapeDesc sphereDesc;
	sphereDesc.radius = radius;
	sphereDesc.mass = 20;

	//set the actor descriptor
	NxActorDesc actorDesc;

	//create the plot of plot
	const int plot = 10;
	NxBoxShapeDesc boxDesc[plot];
	for(int i=0; i<plot; i++)
	{
		boxDesc[i].dimensions.set((float)0.5, (float)0.1, (float)0.1);
		float angle = (float)((2*3.14/plot)*i);
		boxDesc[i].localPose.t = NxVec3(cos(angle)*radius, sin(angle)*radius, 0);
		boxDesc[i].localPose.M.rotZ(angle);
		actorDesc.shapes.push_back(&boxDesc[i]);

	}

	//create the hand
	NxBoxShapeDesc handDesc;
	handDesc.dimensions.set(NxVec3(0.5, 0.5, 0.5));
	handDesc.localPose.t = NxVec3(0, radius+1, 0);
	actorDesc.shapes.push_back(&handDesc);

	//set the actor
	actorDesc.shapes.pushBack(&sphereDesc);
	NxBodyDesc bodyDesc;
	actorDesc.body = &bodyDesc;
	actorDesc.density = 10.0f;
	actorDesc.globalPose.t = position;	
	actorDesc.globalPose.M.rotZ(rotationZ);
	NxActor* gear = m_scene->createActor(actorDesc);

	//create the joint
	NxRevoluteJointDesc joint;
	joint.actor[1] = 0;
	joint.actor[0] = gear;

	NxVec3 anchor = position;

	joint.setGlobalAnchor(anchor);
	joint.setGlobalAxis(NxVec3(0, 0, 1));

	joint.jointFlags =NX_JF_COLLISION_ENABLED;

	joint.projectionMode = NX_JPM_POINT_MINDIST;
	joint.projectionDistance = 0;
	joint.projectionAngle = (float)0.0872;

	NxJoint* newJoint = m_scene->createJoint(joint);
}
void SecondModule::createSeesaw(const NxVec3& position)
{
	NxBoxShapeDesc balanceDesc;
	NxActorDesc actorDesc;

	//balance
	balanceDesc.dimensions.set(2, (float)0.1, 2);
	balanceDesc.localPose.M.rotZ((float)-3.14/6);

	actorDesc.shapes.push_back(&balanceDesc);
	NxBodyDesc body;
	actorDesc.body = &body;
	actorDesc.density = 10.0f;
	actorDesc.globalPose.t = position;

	NxActor* seesaw = m_scene->createActor(actorDesc);

	//create the joint
	NxRevoluteJointDesc joint;
	joint.actor[1] = 0;
	joint.actor[0] = seesaw;

	NxVec3 anchor = position;

	joint.setGlobalAnchor(anchor);
	joint.setGlobalAxis(NxVec3(0, 0, 1));

	joint.jointFlags =NX_JF_COLLISION_ENABLED;

	joint.projectionMode = NX_JPM_POINT_MINDIST;
	joint.projectionDistance = 0;
	joint.projectionAngle = (float)0.0872;

	NxJoint* newJoint = m_scene->createJoint(joint);
}